/*
* @(#)DESUtil.java 2.0 11/11/23
*
* Copyright  2011-2011 Gopay Information and technology Co., Ltd.
* Sanyunqiao, Chaoyang, Beijing, 100027, China.
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Gopay Information and technology Co., Ltd. (“Confidential Information”).
* You shall not disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into with Gopay.
*/

package com.gopay.common.oldmermove.util;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * DESUtil.java类文件描述.
 *
 * @author Gopay
 * @version 2.0 2011-11-23
 */
public class DESUtil {

	/**
	 * 构造器.
	 */
	protected DESUtil() {
		throw new UnsupportedOperationException();
	}

	/**
	 * @param args args
	 * @throws Exception Exception
	 */
	public static void main(String[] args) throws Exception {
		/*byte[] b = getByteArray("0fa61e1b77b51b8a");
		System.out.println("Length:" + b.length);
		System.out.println(new String(b));
		for (int i = 0; i < b.length; i++) {
			System.out.print(b[i] + " ");
		}
		System.out.println("");

		String s = "1111aaaa";
		System.out.println(s);
		byte[] encryptedData = encrypt(s.getBytes(), b);
		for (int i = 0; i < encryptedData.length; i++) {
			System.out.print(encryptedData[i] + " ");
		}
		System.out.println("");
		System.out.println(getHexString(encryptedData));
		System.out.println("");

		byte[] decryptedData = decrypt(encryptedData, b);
		System.out.println(new String(decryptedData));*/
		
		
//		byte[] b1 = FileUtils.readFileToByteArray(new File("d:/20130618115143.pf"));
//		System.out.println("pf file length: " + b1.length);
		
//		String a = FileUtils.readFileToString(new File("d:/20130627162954.pf"));
//		String a1 = decrypt(a, "1122334455667788", MODE_ECB_NOPADDING, "UTF-8");
//		System.out.println(a1);
//		
//		String b1 = decrypt("23095170E28D74E076BC8C6F9A83F3D7C98288F2633C4FA17A5FF55E79F03EBA3D36490D20AAF69B8C6D81A7C4AEB873F308B5FFE6EE21BC0B560697CBC858FAF59A961A3FFF07D8931BB57426B4AE72F27CBC486C4DB7D20B63666F5FF8475A96D2CE0BC53D95A56ACE15660E09CC9AAE34609B0CCDC4F497B7E6C13B00C98551A5A9B60C4128552F9EC4ADD9B86B1C", 
//				"1AC34AE935973415", MODE_ECB_NOPADDING, "UTF-8");
//		System.out.println(b1);
		
//		byte[] d = decrypt(b1, "1122334455667788".getBytes(), MODE_ECB_NOPADDING);
		
//		System.out.println("pf after decrypt length: " + d.length);
		
		/*byte[] key = "1122334455667788".getBytes();
		String a = "12345678";
		String single = "";
		for (int i = 0; i < 10; i++) {
			single += a;
		}
		
		int n = 1000000;
		byte[] s = single.getBytes();
		long start1 = System.currentTimeMillis();
		for (int i = 0; i < n; i++) {
//			System.out.println(single);
			encrypt(s, key);
		}
		long end1 = System.currentTimeMillis();
		
		System.out.println("逐行加密" + n + "次耗时:" + (end1 - start1));
		
		String all = "";
		for (int i = 0; i < n; i++) {
			all += single;
		}
//		System.out.println(all);
		long start2 = System.currentTimeMillis();
		encrypt(all.getBytes(), key);
		long end2 = System.currentTimeMillis();
		System.out.println("整行加密耗时:" + (end2 - start2));*/
		
//		String s = "9DB8DD2AC70D3856511B0ED5EA3CAC4F86F0C5F82C0CD202348F4DDC16616546A0C2F84459EF846254400BC4FFEDCC518EA67EE6F12B55FDC2A0D3EB4AB70CE170D4E6772595EA5F8EAD657E086804DE2C403EB630B8953842431C878580EB8086F3344E3CDAE5D2A5A66A242A8A32BD703030A9496EA63E14A5308F11C20F16DB933A6FEB1324E69DE9DF7A45956E6B5F90665E43AA4488ADA53A31B747AFE090B8FB985A9AF028EB5E3202389140D3B41467F7FEA5E5ACF9A6F7E1BCA4C9AC7FC8C4A9C9164D135CDACBBF6391BBF47C4AF433E0A7D3342FF9F5666583440249D672AA955CF711777FCE7A090D2387737EF240D4FDAE592A14D1E156C98EE813467E614B606417828DB91603E7FE59DB933A6FEB1324E69DE9DF7A45956E6B489C41D74B602718ADA53A31B747AFE090B8FB985A9AF0283CC5EA0F39E995B8B41467F7FEA5E5AC26660C7958D3F2689D86F3AEAA421371C86906D67AD1092984E699D35502C0198DC0FAF2E020BFC7E75D8B02B8B0533F5703A234064F3E0C553CDAB5F8E76441B489008BC18D8AB6661B7B0C7D5E95CA136DCC7CB10DC59CC6D3D6382626B1790EC0887D9754B31E7368EBE2852C042B350FDCAFA7BC43BD641259D14174CA7693B1AF00A78E6B417EBE37AFBC41A3F51853DFD7CD806022E383A9A6C85B3B62AA95A172D3474314CCF23A1D0DA45D9D6E1847B3059F6BBE141D5A40F9D446387FD24A4580C0FDB9F748612A087895A8551BCBD09A02B4A6C39B8C49AD5E487562523E5E2AB520CBCE8C404D948AAB1CB97A4B7B4E657E3B21104335B6DCA9F898803B406A704222E375F07F26C1AE5DE70C0EA5452455022613FCCABB528A36CB4E20641B3E65CC87F1072345559D2A7D390B3639849461DA9491DE668B97159D5E416D426231133109DE0D85A57311C39B8C49AD5E487562523E5E2AB520CB38C08F07C817E59CB97A4B7B4E657E3B21104335B6DCA9F898803B406A7042221E6FA4C25DDE0AA6A2AB4D8FEBCB6EA87EBE37AFBC41A3F51853DFD7CD806022E383A9A6C85B3B62AA95A172D3474314CCF23A1D0DA45D9D6E1847B3059F6BBE7C8CA9A4DD6F75517FD24A4580C0FDB9F748612A087895A8551BCBD09A02B4A6C39B8C49AD5E4875BA60C67334F6DAE6";
//		String s2 = decrypt(s, "1122334455667788", MODE_ECB_NOPADDING);
//		System.out.println(s2);
		
		
//		byte[] b = HexUtil.hexToBytes(s2);
//		System.out.println(new String(b, "UTF-8"));
	}

	/**
	 * decrypt.
	 * @param encryptedData encryptedData
	 * @param key key
	 * @return String
	 */
	public static String decrypt(String encryptedData, String key){
		String ret = null;
		byte[] keyByte = DESUtil.getByteArray(key);
		byte[] byteData = DESUtil.getByteArray(encryptedData.toLowerCase());
		try {
			ret = new String(DESUtil.decrypt(byteData, keyByte));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ret.trim();
	}
	
//	/**
//	 * DES解密(按指定算法).
//	 */
//	public static String decrypt(String encryptedData, String key, String mode, String encoding){
//		String ret = null;
////		byte[] keyByte = DESUtil.getByteArray(key);
////		byte[] byteData = DESUtil.getByteArray(encryptedData.toLowerCase());
//		byte[] keyByte = HexUtil.hexToBytes(key);
//		byte[] byteData = HexUtil.hexToBytes(encryptedData/*.toLowerCase()*/);
//		try {
//			byte[]  t = DESUtil.decrypt(byteData, keyByte, mode);
//			System.out.println(getHexString(t));
//			ret = new String(t, encoding);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		return ret;
//	}

	/**
	 * DES加密.
	 * @param data .
	 * @param b .
	 * @return byte[]
	 * @throws Exception .
	 */
	public static byte[] encrypt(byte[] data, byte[] b) throws Exception {
		DESKeySpec dks = new DESKeySpec(b);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(dks);
		SecureRandom sr = new SecureRandom();
		Cipher cipher = Cipher.getInstance("DES");
		cipher.init(Cipher.ENCRYPT_MODE, key, sr);
		byte[] encryptedData = cipher.doFinal(data);
		return encryptedData;
	}
	
	/**
	 * DES加密后转为16进制的字符串
	 * @param data	明文
	 * @param b		密钥
	 * @return
	 * @throws Exception
	 */
	public static String encrypt2HexString(String data, String b) throws Exception {
		byte[] encryptedData = encrypt(data.getBytes(), getByteArray(b));
		return getHexString(encryptedData);
	}

	/**
	 * DES解密.
	 * @param data .
	 * @param b .
	 * @return byte[]
	 * @throws Exception .
	 */
	public static byte[] decrypt(byte[] data, byte[] b) throws Exception {
		DESKeySpec dks = new DESKeySpec(b);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(dks);
		SecureRandom sr = new SecureRandom();
		Cipher cipher = Cipher.getInstance("DES");
		cipher.init(Cipher.DECRYPT_MODE, key, sr);
		byte[] decryptedData = cipher.doFinal(data);
		return decryptedData;
	}
	
	// ECB模式
	public static final String MODE_ECB_NOPADDING = "DES/ECB/NOPadding";
	
	/**
	 * DES解密(按指定算法).
	 * @param data .
	 * @param b .
	 * @return byte[]
	 * @throws Exception .
	 */
	public static byte[] decrypt(byte[] data, byte[] b, String mode) throws Exception {
		DESKeySpec dks = new DESKeySpec(b);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(dks);
		SecureRandom sr = new SecureRandom();
		Cipher cipher = Cipher.getInstance(mode);
		cipher.init(Cipher.DECRYPT_MODE, key, sr);
		byte[] decryptedData = cipher.doFinal(data);
		return decryptedData;
	}

	/**
	 * 随机生成密钥.
	 * @return byte[]
	 * @throws Exception .
	 */
	public static byte[] getKey() throws Exception {
		SecureRandom sr = new SecureRandom();
		KeyGenerator kg = KeyGenerator.getInstance("DES");
		kg.init(sr);
		SecretKey key = kg.generateKey();
		byte[] b = key.getEncoded();
		return b;
	}

	/**
	 * byte数组转换成16进制字符串.
	 * @param b .
	 * @return String
	 */
	public static String getHexString(byte[] b) {
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			result.append(hex.toLowerCase());
		}
		return result.toString();
	}

	/**
	 * 16进制字符串转换成byte数组.
	 * @param hex .
	 * @return byte[]
	 */
	public static byte[] getByteArray(String hex){
		int len = (hex.length() / 2);
		byte[] result = new byte[len];
		char[] achar = hex.toCharArray();
		for(int i=0;i<len;i++){
			int pos = i*2;
			result[i] = (byte)(toByte(achar[pos])<<4 |toByte(achar[pos+1]));
		}
		return result;
	}

	/**
	 * toByte.
	 * @param c c
	 * @return int
	 */
	private static int toByte(char c) {
		byte b = (byte)"0123456789abcdef".indexOf(c);
		return b;
	}
}
